<template>
  <div class="complex-table table-container">
    <!-- 表头搜索 -->
    <table-search :buttons="tableButtonBars" :table-selection="tableSelection" :table-total="tableTotal" @simpleSearch="simpleSearch" />

    <!-- 表格数据 -->
    <el-table
      v-loading="loading"
      border
      :data="tableData"
      :height="tableFull()"
      :row-key="datas.rowKey"
      class="filter-table"
      @selection-change="selectionChange"
      @sort-change="changeSort"
    >
      <template v-for="(item, index) in tableCols">
        <!-- 多选框 -->
        <el-table-column
          v-if="checkColSelection(item)"
          :key="index"
          :align="item.align || 'center'"
          :width="item.width || 40"
          :fixed="item.fixed"
          :disabled="true"
          type="selection"
        />

        <!-- 操作栏 -->
        <el-table-column
          v-else-if="checkColToolBar(item)"
          :key="index"
          :label="item.$label"
          :fixed="item.fixed || 'right'"
          :align="item.align || 'center'"
          :width="item.width || 260"
        >
          <template slot-scope="scope">
            <template v-if="item.actions">
              <template v-for="(action, actionIndex) in item.actions">
                <el-button
                  v-if="action.show ? action.show(scope.row) : true"
                  :key="actionIndex"
                  :type="action.type || 'text'"
                  :icon="action.icon"
                  :disabled="action.disabled ? action.disabled(scope.row) : false"
                  @click="action.event ? action.event(scope.row, $event) : false"
                >{{ $labelVal(action) }}</el-button>
              </template>
            </template>
          </template>
        </el-table-column>

        <el-table-column
          v-else
          :key="item.id"
          :min-width="getColTypeDefWidth(item.type, item.width)"
          :align="item.align"
          :fixed="item.fixed"
          :sortable="item.sort ? 'custom' : false"
          :label="item.$label"
          :prop="item.$prop"
          :show-overflow-tooltip="true"
        >
          <template slot-scope="scope">
            <!-- html -->
            <span v-if="getLowerCaseVal(item.type) === 'html'" v-html="getColValue(item, scope.row)" />

            <!-- 时间字段 -->
            <span v-else-if="isDateTimeField(item.type)">
              {{ getColValue(item, scope.row) | parseTime(getColTypeDefFormat(item.type)) }}
            </span>

            <!-- Tag 标签 -->
            <template v-else-if="getLowerCaseVal(item.type) === 'tag' && item.selections">
              <template v-for="(selection, selectionIndex) in item.selections">
                <template v-if="(getColValue(item, scope.row)).toString() === (selection.value).toString()">
                  <el-tag
                    :type="selection.type"
                    :hit="selection.hit"
                    :color="selection.color"
                    :effect="selection.effect"
                  >{{ getLabelValue(selection) }}</el-tag>
                </template>
              </template>
            </template>

            <!-- selections -->
            <template v-else-if="getLowerCaseVal(item.type) === 'selections' && item.selections">
              <template v-for="(selection, selectionIndex) in item.selections">
                <template v-if="(getColValue(item, scope.row)).toString() === (selection.value).toString()">
                  <el-button
                    v-if="selection.event"
                    :key="selectionIndex"
                    type="text"
                    :icon="selection.icon"
                    :disabled="selection.disabled ? selection.disabled(scope.row) : false"
                    @click="selection.event($event, getPropValue(item), scope.row, item)"
                  >{{ getLabelValue(selection) }}</el-button>
                  <span v-else :key="selectionIndex">{{ getLabelValue(selection) }}</span>
                </template>
              </template>
            </template>

            <!-- switch 开关 -->
            <template v-else-if="getLowerCaseVal(item.type) === 'switch'">
              <el-switch
                class="inline-text no-select"
                :value="getColValue(item, scope.row)"
                :active-color="item.switch.activeColor"
                :inactive-color="item.switch.inactiveColor"
                :active-text="item.switch.activeText"
                :inactive-text="item.switch.inactiveText"
                :active-value="item.switch.activeValue"
                :inactive-value="item.switch.inactiveValue"
                :disabled="item.disabled || item.readonly"
                @change="item.event ? item.event($event, getPropValue(item), scope.row, item) : false"
              />
            </template>

            <!-- icon 图标 -->
            <template v-else-if="getLowerCaseVal(item.type) === 'icon'">
              <i v-if="isElementIcon(getColValue(item, scope.row))" :class="getColValue(item, scope.row)" />
              <svg-icon v-else :icon-class="getColValue(item, scope.row)" />
            </template>

            <!-- 默认 -->
            <span v-else>{{ getColValue(item, scope.row) }}</span>
          </template>
        </el-table-column>
      </template>
    </el-table>

    <!-- 表格分页 -->
    <table-pagination
      :select-number="selectNumber"
      :total="tableTotal"
      :page="isPage"
      @handleCurrentChange="handleCurrentChange"
      @handleSizeChange="handleSizeChange"
    />
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import TableSearch from './components/TableSearch'
import TablePagination from './components/TablePagination'
import validate from '@/utils/validate'
import search from '@/utils/search'

export default {
  name: 'ComplexTable'
  , components: {
    TablePagination
    , TableSearch
  }
  , props: {
    datas: {
      type: Object
      , default: () => {
        return {
        }
      }
    }
  }

  , data() {
    return {
      filters: {
        isComplex: false
        , searchText: ''
      }

      // 搜索字段
      , searchFields: []
      // 高级收搜高度
      , complexFilterHeight: 0
      // 表格数据选择
      , tableSelection: null
      // 表格加载 loading
      , loading: false
      , currentPage: 1
      , tableTotal: 0
      , tableData: []
      // 排序
      , sort: []
    }
  }

  , computed: {
    ...mapGetters([
      'fullHeight'
      , 'tableDefConfig'
    ])
    , tableCols: {
      get() {
        const cols = this.datas.cols.length !== 1 ? this.datas.cols : this.datas.cols[0]
        return cols.map((item) => {
          return this.handleFieldLabels(item)
        })
      }
    }

    , tableButtonBars: {
      get() {
        return (this.datas.buttonBars && this.datas.buttonBars.length > 0 ? this.datas.buttonBars : []).map((item) => {
          return this.handleFieldLabels(item)
        })
      }
    }

    // 处理树形菜单时,分页数据
    , isPage: {
      get() {
        return validate.isBlank(this.datas.rowKey) || this.datas.page === true
      }
    }

    // 搜索字段
    , tableSearchFields: {
      get() {
        if (this.tableCols && this.tableCols.length > 0) {
          return this.tableCols.filter((item) => {
            return item && item.search
          })
        }
        return null
      }
    }

    // 禁止删除ID
    , prohibitDelIds: {
      get() {
        return this.datas.prohibitDelIds ? this.datas.prohibitDelIds : []
      }
    }
    // 选择数量
    , selectNumber: {
      get() {
        const val = this.tableSelection
        return validate.notEmpty(val) ? (val.filter(row => this.prohibitDelIds.indexOf(row.id) === -1)).length : 0
      }
    }
  }

  , mounted() {

  }

  , beforeDestroy() {

  }

  , created() {
    // 设置收搜字段
    this.searchFields = this.tableSearchFields
    // 获取列表数据
    this.getList()
  }

  , methods: {
    getList() {
      this.loading = true
      if (this.datas && this.datas.data && this.datas.data.length > 0) {
        this.tableTotal = this.datas.data.length
        this.tableData = this.datas.data
        this.loading = false
      } else if (this.datas && typeof this.datas.searchList === 'function') {
        this.datas.searchList(search.getQueryParams(this)).then(res => {
          const data = res && res.data ? res.data : {}
          if (this.currentPage > data.totalRows) {
            this.currentPage = data.totalRows
            this.getList()
          }

          this.tableData = data.rows
          this.tableTotal = data.total
          this.loading = false
        })
      }
    }

    // 简单搜索
    , simpleSearch(text) {
      this.filters.searchText = text
      this.getList()
    }
    // 检查复选框
    , checkColSelection(item) {
      return ['selection', 'checkbox'].indexOf(this.getLowerCaseVal(item.type)) !== -1 &&
        !Object.prototype.hasOwnProperty.call(item, 'prop') &&
        !Object.prototype.hasOwnProperty.call(item, 'field') &&
        !Object.prototype.hasOwnProperty.call(item, 'toolbar')
    }

    // 检查行工具条
    , checkColToolBar(item) {
      return (this.getLowerCaseVal(item.type) === 'toolbar' || Object.prototype.hasOwnProperty.call(item, 'toolbar')) &&
      !Object.prototype.hasOwnProperty.call(item, 'prop') &&
      !Object.prototype.hasOwnProperty.call(item, 'field')
    }

    // 获取表格标题
    , getLabelValue(item) {
      if (Object.prototype.hasOwnProperty.call(item, 'title') && validate.notBlank(item.title)) {
        return item.title
      }
      return item.label
    }

    // 获取绑定字段
    , getPropValue(item) {
      if (Object.prototype.hasOwnProperty.call(item, 'field') && validate.notBlank(item.field)) {
        return item.field
      } else if (Object.prototype.hasOwnProperty.call(item, 'name') && validate.notBlank(item.name)) {
        return item.name
      }
      return item.prop
    }

    // 获取表格字段数据
    , getColValue(item, row) {
      // 获取字段名称
      const field = this.getPropValue(item)
      // 获取字段值
      return row[field]
    }

    // 获取表格特殊字段默认宽度
    , getColTypeDefWidth(type, defValue) {
      if (defValue === undefined || defValue === '' || defValue === null) {
        // 时间字段
        if (this.isDateTimeField(type)) {
          defValue = this.getDateTimeFieldConfig(type).width
        }
      }
      return defValue
    }

    // 获取表格特殊字段默认格式
    , getColTypeDefFormat(type, defValue) {
      // 时间字段
      if (this.isDateTimeField(type)) {
        return this.getDateTimeFieldConfig(type).format
      }
      return defValue
    }

    // 获取时间字段配置
    , getDateTimeFieldConfig(type) {
      return this.tableDefConfig.dateTimeStyle[this.getLowerCaseVal(type)]
    }

    // 检查是否为时间字段
    , isDateTimeField(type) {
      return Object.prototype.hasOwnProperty.call(this.tableDefConfig.dateTimeStyle, this.getLowerCaseVal(type))
    }

    // 值转小写
    , getLowerCaseVal(val) {
      return String(val).toLowerCase().replace('-', '')
    }

    // 表格高度
    , tableFull() {
      if (this.datas.height > 0) {
        return this.datas.height
      }

      let full = this.datas.full > 0 ? this.datas.full : 0
      // 添加高级搜索高度
      full = this.filters.isComplex ? full + this.complexFilterHeight : full

      // 计算高度
      return this.z_fullNum(this.fullHeight, full)
    }

    // 表格数据选择
    , selectionChange(val) {
      this.tableSelection = val
    }

    // 表格排序
    , changeSort(val) {
      this.sort = val
      this.getList()
    }

    // 选择页数
    , handleCurrentChange(val) {
      this.currentPage = val
      // 重新获取数据
      this.getList()
    }

    // 选择条数
    , handleSizeChange(pageSize, currentPage) {
      this.pageSize = pageSize
      this.currentPage = currentPage
      // 重新获取数据
      this.getList()
    }

    , getIconHtml(index) {
      return '<svg-icon icon-class="404" />'
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss">
  .complex-table.table-container .filter-table {
    .el-table__header th{
      background: #f2f2f2;
    }

    .el-table__header tr th:nth-last-child(2),
    .el-table__body .el-table__row td:last-child{
      border-right-width: 0;
    }

    .el-table__body td.el-table-column--selection .cell{
      padding-right: 0.625rem;
    }
  }
</style>

<!-- 样式 -->
<style rel="stylesheet/scss" lang="scss" scoped>
  @import "@/styles/element-variables.scss";
  $bg: #fff;
  $space: 0.625rem;

  .complex-table.table-container {
    background-color: $bg;
    border: 1px solid $--border-color-light;
    border-radius: 4px;
    overflow: hidden;

    .filter-table {
      border-left-width: 0;

      &::after,
      &::before {
        background-color: transparent;
      }
    }
  }
</style>
